package com.yinduo.yongyou.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.yinduo.yongyou.R;
import com.yinduo.yongyou.listener.OnTabSelectListener;

import java.util.ArrayList;


/** 滑动TabLayout,对于ViewPager的依赖性强 */
public class FixedSlidingTabLayout extends HorizontalScrollView implements
		ViewPager.OnPageChangeListener {
	private Context mContext;
	private ViewPager mViewPager;
	private String[] mTitles;
	private LinearLayout mTabsContainer;
	private int mCurrentTab;
	private float mCurrentPositionOffset;
	private int mTabCount;
	/** 用于绘制显示器 */
	private Rect mIndicatorRect = new Rect();
	/** 用于实现滚动居中 */
	private Rect mTabRect = new Rect();
	private GradientDrawable mIndicatorDrawable = new GradientDrawable();

	private Paint mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
	private Paint mDividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
	private Paint mTrianglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
	private Path mTrianglePath = new Path();
	private static final int STYLE_NORMAL = 0;
	private static final int STYLE_TRIANGLE = 1;
	private static final int STYLE_BLOCK = 2;
	private int mIndicatorStyle = STYLE_NORMAL;

	private float mTabPadding;
	private boolean mTabSpaceEqual;
	private float mTabWidth;

	/** indicator */
	private int mIndicatorColor;
	private float mIndicatorHeight;
	private float mIndicatorWidth;
	private float mIndicatorCornerRadius;
	private float mIndicatorMarginLeft;
	private float mIndicatorMarginTop;
	private float mIndicatorMarginRight;
	private float mIndicatorMarginBottom;
	private int mIndicatorGravity;
	private boolean mIndicatorWidthEqualTitle;

	/** underline */
	private int mUnderlineColor;
	private float mUnderlineHeight;
	private int mUnderlineGravity;

	/** divider */
	private int mDividerColor;
	private float mDividerWidth;
	private float mDividerPadding;

	/** title */
	private float mTextsize;
	private int mTextSelectColor;
	private int mTextUnselectColor;
	private boolean mTextBold;
	private boolean mTextAllCaps;

	private int mLastScrollX;
	private int mHeight;

	public FixedSlidingTabLayout(Context context) {
		this(context, null, 0);
	}

	public FixedSlidingTabLayout(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public FixedSlidingTabLayout(Context context, AttributeSet attrs,
								 int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		setFillViewport(true);// 设置滚动视图是否可以伸缩其内容以填充视口
		setWillNotDraw(false);// 重写onDraw方法,需要调用这个方法来清除flag
		setClipChildren(false);
		setClipToPadding(false);

		this.mContext = context;
		mTabsContainer = new LinearLayout(context);
		mTabsContainer
				.setLayoutParams(new LinearLayout.LayoutParams(
						-1, -1));

		addView(mTabsContainer);

		obtainAttributes(context, attrs);

		// get layout_height
		String height = attrs.getAttributeValue(
				"http://schemas.android.com/apk/res/android", "layout_height");

		// create ViewPager
		if (height.equals(ViewGroup.LayoutParams.MATCH_PARENT + "")) {
		} else if (height.equals(ViewGroup.LayoutParams.WRAP_CONTENT + "")) {
		} else {
			int[] systemAttrs = { android.R.attr.layout_height };
			TypedArray a = context.obtainStyledAttributes(attrs, systemAttrs);
			mHeight = a.getDimensionPixelSize(0,
					ViewGroup.LayoutParams.WRAP_CONTENT);
			a.recycle();
		}
	}

	private void obtainAttributes(Context context, AttributeSet attrs) {
		TypedArray ta = context.obtainStyledAttributes(attrs,
				R.styleable.SlidingTabLayout);

		mIndicatorStyle = ta.getInt(
				R.styleable.SlidingTabLayout_tl_indicator_style, STYLE_NORMAL);
		mIndicatorColor = ta.getColor(
				R.styleable.SlidingTabLayout_tl_indicator_color, Color
						.parseColor(mIndicatorStyle == STYLE_BLOCK ? "#4B6A87"
								: "#ffffff"));
		mIndicatorHeight = ta.getDimension(
				R.styleable.SlidingTabLayout_tl_indicator_height,
				dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 4
						: (mIndicatorStyle == STYLE_BLOCK ? -1 : 2)));
		mIndicatorWidth = ta.getDimension(
				R.styleable.SlidingTabLayout_tl_indicator_width,
				dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 10 : -1));
		mIndicatorCornerRadius = ta.getDimension(
				R.styleable.SlidingTabLayout_tl_indicator_corner_radius,
				dp2px(mIndicatorStyle == STYLE_BLOCK ? -1 : 0));
		mIndicatorMarginLeft = ta
				.getDimension(
						R.styleable.SlidingTabLayout_tl_indicator_margin_left,
						dp2px(0));
		mIndicatorMarginTop = ta.getDimension(
				R.styleable.SlidingTabLayout_tl_indicator_margin_top,
				dp2px(mIndicatorStyle == STYLE_BLOCK ? 7 : 0));
		mIndicatorMarginRight = ta.getDimension(
				R.styleable.SlidingTabLayout_tl_indicator_margin_right,
				dp2px(0));
		mIndicatorMarginBottom = ta.getDimension(
				R.styleable.SlidingTabLayout_tl_indicator_margin_bottom,
				dp2px(mIndicatorStyle == STYLE_BLOCK ? 7 : 0));
		mIndicatorGravity = ta.getInt(
				R.styleable.SlidingTabLayout_tl_indicator_gravity,
				Gravity.BOTTOM);
		mIndicatorWidthEqualTitle = ta.getBoolean(
				R.styleable.SlidingTabLayout_tl_indicator_width_equal_title,
				false);

		mUnderlineColor = ta.getColor(
				R.styleable.SlidingTabLayout_tl_underline_color,
				Color.parseColor("#ffffff"));
		mUnderlineHeight = ta.getDimension(
				R.styleable.SlidingTabLayout_tl_underline_height, dp2px(0));
		mUnderlineGravity = ta.getInt(
				R.styleable.SlidingTabLayout_tl_underline_gravity,
				Gravity.BOTTOM);

		mDividerColor = ta.getColor(
				R.styleable.SlidingTabLayout_tl_divider_color,
				Color.parseColor("#ffffff"));
		mDividerWidth = ta.getDimension(
				R.styleable.SlidingTabLayout_tl_divider_width, dp2px(0));
		mDividerPadding = ta.getDimension(
				R.styleable.SlidingTabLayout_tl_divider_padding, dp2px(12));

		mTextsize = ta.getDimension(R.styleable.SlidingTabLayout_tl_textsize,
				sp2px(14));
		mTextSelectColor = ta.getColor(
				R.styleable.SlidingTabLayout_tl_textSelectColor,
				Color.parseColor("#ffffff"));
		mTextUnselectColor = ta.getColor(
				R.styleable.SlidingTabLayout_tl_textUnselectColor,
				Color.parseColor("#AAffffff"));
		mTextBold = ta.getBoolean(R.styleable.SlidingTabLayout_tl_textBold,
				false);
		mTextAllCaps = ta.getBoolean(
				R.styleable.SlidingTabLayout_tl_textAllCaps, false);

		mTabSpaceEqual = ta.getBoolean(
				R.styleable.SlidingTabLayout_tl_tab_space_equal, false);
		mTabWidth = ta.getDimension(R.styleable.SlidingTabLayout_tl_tab_width,
				dp2px(-1));
		mTabPadding = ta.getDimension(
				R.styleable.SlidingTabLayout_tl_tab_padding, mTabSpaceEqual
						|| mTabWidth > 0 ? dp2px(0) : dp2px(20));

		ta.recycle();
	}

	/** 关联ViewPager */
	public void setViewPager(ViewPager vp) {
		if (vp == null || vp.getAdapter() == null) {
			throw new IllegalStateException(
					"ViewPager or ViewPager adapter can not be NULL !");
		}

		this.mViewPager = vp;

		this.mViewPager.removeOnPageChangeListener(this);
		this.mViewPager.addOnPageChangeListener(this);
		notifyDataSetChanged();
	}

	/** 关联ViewPager,用于不想在ViewPager适配器中设置titles数据的情况 */
	public void setViewPager(ViewPager vp, String[] titles) {
		if (vp == null || vp.getAdapter() == null) {
			throw new IllegalStateException(
					"ViewPager or ViewPager adapter can not be NULL !");
		}

		if (titles == null || titles.length == 0) {
			throw new IllegalStateException("Titles can not be EMPTY !");
		}

//		if (titles.length != vp.getAdapter().getCount()) {
//			throw new IllegalStateException(
//					"Titles length must be the same as the page count !");
//		}

		this.mViewPager = vp;
		this.mTitles = titles;

		this.mViewPager.removeOnPageChangeListener(this);
		this.mViewPager.addOnPageChangeListener(this);
		notifyDataSetChanged();
	}

	/** 关联ViewPager,用于连适配器都不想自己实例化的情况 */
	public void setViewPager(ViewPager vp, String[] titles,
							 FragmentActivity fa, ArrayList<Fragment> fragments) {
		if (vp == null) {
			throw new IllegalStateException("ViewPager can not be NULL !");
		}

		if (titles == null || titles.length == 0) {
			throw new IllegalStateException("Titles can not be EMPTY !");
		}

		this.mViewPager = vp;
		this.mViewPager.setAdapter(new InnerPagerAdapter(fa
				.getSupportFragmentManager(), fragments, titles));

		this.mViewPager.removeOnPageChangeListener(this);
		this.mViewPager.addOnPageChangeListener(this);
		notifyDataSetChanged();
	}

	/** 更新数据 */
	public void notifyDataSetChanged() {
		mTabsContainer.removeAllViews();
		this.mTabCount = mTitles == null ? mViewPager.getAdapter().getCount()
				: mTitles.length;
		View tabView;
		for (int i = 0; i < mTabCount; i++) {
			if (mViewPager.getAdapter() instanceof CustomTabProvider) {
				tabView = ((CustomTabProvider) mViewPager.getAdapter())
						.getCustomTabView(this, i);
			} else {
				tabView = View.inflate(mContext, R.layout.layout_tab, null);
			}

			CharSequence pageTitle = mTitles == null ? mViewPager.getAdapter()
					.getPageTitle(i) : mTitles[i];
			addTab(i, pageTitle.toString(), tabView);
		}

		updateTabStyles();
	}

	/** 创建并添加tab */
	private void addTab(final int position, String title, View tabView) {
		TextView tv_tab_title = (TextView) tabView
				.findViewById(R.id.tv_tab_title);
		if (tv_tab_title != null) {
			if (title != null)
				tv_tab_title.setText(title);
		}

		tabView.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (mViewPager.getCurrentItem() != position) {
					mViewPager.setCurrentItem(position);
					if (mListener != null) {
						mListener.onTabSelect(position);
					}
				} else {
					if (mListener != null) {
						mListener.onTabReselect(position);
					}
				}
			}
		});

		/** 每一个Tab的布局参数 */
		LinearLayout.LayoutParams lp_tab = mTabSpaceEqual ? new LinearLayout.LayoutParams(
				0, ViewGroup.LayoutParams.MATCH_PARENT, 1.0f)
				: new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
				ViewGroup.LayoutParams.MATCH_PARENT);
		if (mTabWidth > 0) {
			lp_tab = new LinearLayout.LayoutParams((int) mTabWidth,
					ViewGroup.LayoutParams.MATCH_PARENT);
		}
		lp_tab.weight=1;
		mTabsContainer.addView(tabView, position, lp_tab);
	}

	private void updateTabStyles() {
		for (int i = 0; i < mTabCount; i++) {
			View v = mTabsContainer.getChildAt(i);
			// v.setPadding((int) mTabPadding, v.getPaddingTop(), (int)
			// mTabPadding, v.getPaddingBottom());
			TextView tv_tab_title = (TextView) v
					.findViewById(R.id.tv_tab_title);
			if (tv_tab_title != null) {
				tv_tab_title.setTextColor(i == mCurrentTab ? mTextSelectColor
						: mTextUnselectColor);
				tv_tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextsize);
				tv_tab_title.setPadding((int) mTabPadding, 0,
						(int) mTabPadding, 0);
				if (mTextAllCaps) {
					tv_tab_title.setText(tv_tab_title.getText().toString()
							.toUpperCase());
				}

				if (mTextBold) {
					tv_tab_title.getPaint().setFakeBoldText(mTextBold);
				}
			}
		}
	}

	@Override
	public void onPageScrolled(int position, float positionOffset,
							   int positionOffsetPixels) {
		/**
		 * position:当前View的位置 mCurrentPositionOffset:当前View的偏移量比例.[0,1)
		 */
		this.mCurrentTab = position;
		this.mCurrentPositionOffset = positionOffset;
		scrollToCurrentTab();
		invalidate();
	}

	@Override
	public void onPageSelected(int position) {
		updateTabSelection(position);
	}

	@Override
	public void onPageScrollStateChanged(int state) {
	}

	/** HorizontalScrollView滚到当前tab,并且居中显示 */
	private void scrollToCurrentTab() {
		if (mTabCount <= 0) {
			return;
		}

		int offset = (int) (mCurrentPositionOffset * mTabsContainer.getChildAt(
				mCurrentTab).getWidth());
		/** 当前Tab的left+当前Tab的Width乘以positionOffset */
		int newScrollX = mTabsContainer.getChildAt(mCurrentTab).getLeft()
				+ offset;

		if (mCurrentTab > 0 || offset > 0) {
			/** HorizontalScrollView移动到当前tab,并居中 */
			newScrollX -= getWidth() / 2 - getPaddingLeft();
			calcIndicatorRect();
			newScrollX += ((mTabRect.right - mTabRect.left) / 2);
		}

		if (newScrollX != mLastScrollX) {
			mLastScrollX = newScrollX;
			/**
			 * scrollTo（int x,int y）:x,y代表的不是坐标点,而是偏移量 x:表示离起始位置的x水平方向的偏移量
			 * y:表示离起始位置的y垂直方向的偏移量
			 */
			scrollTo(newScrollX, 0);
		}
	}

	private void updateTabSelection(int position) {
		for (int i = 0; i < mTabCount; ++i) {
			View tabView = mTabsContainer.getChildAt(i);
			final boolean isSelect = i == position;
			TextView tab_title = (TextView) tabView
					.findViewById(R.id.tv_tab_title);

			if (tab_title != null) {
				tab_title.setTextColor(isSelect ? mTextSelectColor
						: mTextUnselectColor);
			}

			if (mViewPager.getAdapter() instanceof CustomTabProvider) {
				if (isSelect) {
					((CustomTabProvider) mViewPager.getAdapter())
							.tabSelect(tabView);
				} else {
					((CustomTabProvider) mViewPager.getAdapter())
							.tabUnselect(tabView);
				}
			}
		}
	}

	private float margin;

	private void calcIndicatorRect() {
		View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);
		float left = currentTabView.getLeft();
		float right = currentTabView.getRight();

		// for mIndicatorWidthEqualTitle
		if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {
			TextView tab_title = (TextView) currentTabView
					.findViewById(R.id.tv_tab_title);
			mTextPaint.setTextSize(mTextsize);
			float textWidth = mTextPaint.measureText(tab_title.getText()
					.toString());
			margin = (right - left - textWidth) / 2;
		}

		if (this.mCurrentTab < mTabCount - 1) {
			View nextTabView = mTabsContainer.getChildAt(this.mCurrentTab + 1);
			float nextTabLeft = nextTabView.getLeft();
			float nextTabRight = nextTabView.getRight();

			left = left + mCurrentPositionOffset * (nextTabLeft - left);
			right = right + mCurrentPositionOffset * (nextTabRight - right);

			// for mIndicatorWidthEqualTitle
			if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {
				TextView next_tab_title = (TextView) nextTabView
						.findViewById(R.id.tv_tab_title);
				mTextPaint.setTextSize(mTextsize);
				float nextTextWidth = mTextPaint.measureText(next_tab_title
						.getText().toString());
				float nextMargin = (nextTabRight - nextTabLeft - nextTextWidth) / 2;
				margin = margin + mCurrentPositionOffset
						* (nextMargin - margin);
			}
		}

		mIndicatorRect.left = (int) left;
		mIndicatorRect.right = (int) right;
		// for mIndicatorWidthEqualTitle
		if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {
			mIndicatorRect.left = (int) (left + margin - 1);
			mIndicatorRect.right = (int) (right - margin - 1);
		}

		mTabRect.left = (int) left;
		mTabRect.right = (int) right;

		if (mIndicatorWidth < 0) { // indicatorWidth小于0时,原jpardogo's
			// PagerSlidingTabStrip

		} else {// indicatorWidth大于0时,圆角矩形以及三角形
			float indicatorLeft = currentTabView.getLeft()
					+ (currentTabView.getWidth() - mIndicatorWidth) / 2;

			if (this.mCurrentTab < mTabCount - 1) {
				View nextTab = mTabsContainer.getChildAt(this.mCurrentTab + 1);
				indicatorLeft = indicatorLeft
						+ mCurrentPositionOffset
						* (currentTabView.getWidth() / 2 + nextTab.getWidth() / 2);
			}

			mIndicatorRect.left = (int) indicatorLeft;
			mIndicatorRect.right = (int) (mIndicatorRect.left + mIndicatorWidth);
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		if (isInEditMode() || mTabCount <= 0) {
			return;
		}

		int height = getHeight();
		int paddingLeft = getPaddingLeft();
		// draw divider
		if (mDividerWidth > 0) {
			mDividerPaint.setStrokeWidth(mDividerWidth);
			mDividerPaint.setColor(mDividerColor);
			for (int i = 0; i < mTabCount - 1; i++) {
				View tab = mTabsContainer.getChildAt(i);
				canvas.drawLine(paddingLeft + tab.getRight(), mDividerPadding,
						paddingLeft + tab.getRight(), height - mDividerPadding,
						mDividerPaint);
			}
		}

		// draw underline
		if (mUnderlineHeight > 0) {
			mRectPaint.setColor(mUnderlineColor);
			if (mUnderlineGravity == Gravity.BOTTOM) {
				canvas.drawRect(paddingLeft, height - mUnderlineHeight,
						mTabsContainer.getWidth() + paddingLeft, height,
						mRectPaint);
			} else {
				canvas.drawRect(paddingLeft, 0, mTabsContainer.getWidth()
						+ paddingLeft, mUnderlineHeight, mRectPaint);
			}
		}

		// draw indicator line

		calcIndicatorRect();
		if (mIndicatorStyle == STYLE_TRIANGLE) {
			if (mIndicatorHeight > 0) {
				mTrianglePaint.setColor(mIndicatorColor);
				mTrianglePath.reset();
				mTrianglePath.moveTo(paddingLeft + mIndicatorRect.left, height);
				mTrianglePath.lineTo(paddingLeft + mIndicatorRect.left / 2
						+ mIndicatorRect.right / 2, height - mIndicatorHeight);
				mTrianglePath
						.lineTo(paddingLeft + mIndicatorRect.right, height);
				mTrianglePath.close();
				canvas.drawPath(mTrianglePath, mTrianglePaint);
			}
		} else if (mIndicatorStyle == STYLE_BLOCK) {
			if (mIndicatorHeight < 0) {
				mIndicatorHeight = height - mIndicatorMarginTop
						- mIndicatorMarginBottom;
			} else {

			}

			if (mIndicatorHeight > 0) {
				if (mIndicatorCornerRadius < 0
						|| mIndicatorCornerRadius > mIndicatorHeight / 2) {
					mIndicatorCornerRadius = mIndicatorHeight / 2;
				}

				mIndicatorDrawable.setColor(mIndicatorColor);
				mIndicatorDrawable
						.setBounds(
								paddingLeft + (int) mIndicatorMarginLeft
										+ mIndicatorRect.left,
								(int) mIndicatorMarginTop,
								(int) (paddingLeft + mIndicatorRect.right - mIndicatorMarginRight),
								(int) (mIndicatorMarginTop + mIndicatorHeight));
				mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);
				mIndicatorDrawable.draw(canvas);
			}
		} else {
			/*
			 * mRectPaint.setColor(mIndicatorColor); calcIndicatorRect();
			 * canvas.drawRect(getPaddingLeft() + mIndicatorRect.left,
			 * getHeight() - mIndicatorHeight, mIndicatorRect.right +
			 * getPaddingLeft(), getHeight(), mRectPaint);
			 */

			if (mIndicatorHeight > 0) {
				mIndicatorDrawable.setColor(mIndicatorColor);

				if (mIndicatorGravity == Gravity.BOTTOM) {
					mIndicatorDrawable.setBounds(paddingLeft
									+ (int) mIndicatorMarginLeft + mIndicatorRect.left,
							height - (int) mIndicatorHeight
									- (int) mIndicatorMarginBottom, paddingLeft
									+ mIndicatorRect.right
									- (int) mIndicatorMarginRight, height
									- (int) mIndicatorMarginBottom);
				} else {
					mIndicatorDrawable.setBounds(paddingLeft
									+ (int) mIndicatorMarginLeft + mIndicatorRect.left,
							(int) mIndicatorMarginTop, paddingLeft
									+ mIndicatorRect.right
									- (int) mIndicatorMarginRight,
							(int) mIndicatorHeight + (int) mIndicatorMarginTop);
				}
				mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);
				mIndicatorDrawable.draw(canvas);
			}
		}
	}

	// setter and getter
	public void setCurrentTab(int currentTab) {
		this.mCurrentTab = currentTab;
		mViewPager.setCurrentItem(currentTab);
	}

	public void setIndicatorStyle(int indicatorStyle) {
		this.mIndicatorStyle = indicatorStyle;
		invalidate();
	}

	public void setTabPadding(float tabPadding) {
		this.mTabPadding = dp2px(tabPadding);
		updateTabStyles();
	}

	public void setTabSpaceEqual(boolean tabSpaceEqual) {
		this.mTabSpaceEqual = tabSpaceEqual;
		updateTabStyles();
	}

	public void setTabWidth(float tabWidth) {
		this.mTabWidth = dp2px(tabWidth);
		updateTabStyles();
	}

	public void setIndicatorColor(int indicatorColor) {
		this.mIndicatorColor = indicatorColor;
		invalidate();
	}

	public void setIndicatorHeight(float indicatorHeight) {
		this.mIndicatorHeight = dp2px(indicatorHeight);
		invalidate();
	}

	public void setIndicatorWidth(float indicatorWidth) {
		this.mIndicatorWidth = dp2px(indicatorWidth);
		invalidate();
	}

	public void setIndicatorCornerRadius(float indicatorCornerRadius) {
		this.mIndicatorCornerRadius = dp2px(indicatorCornerRadius);
		invalidate();
	}

	public void setIndicatorGravity(int indicatorGravity) {
		this.mIndicatorGravity = indicatorGravity;
		invalidate();
	}

	public void setIndicatorMargin(float indicatorMarginLeft,
								   float indicatorMarginTop, float indicatorMarginRight,
								   float indicatorMarginBottom) {
		this.mIndicatorMarginLeft = dp2px(indicatorMarginLeft);
		this.mIndicatorMarginTop = dp2px(indicatorMarginTop);
		this.mIndicatorMarginRight = dp2px(indicatorMarginRight);
		this.mIndicatorMarginBottom = dp2px(indicatorMarginBottom);
		invalidate();
	}

	public void setIndicatorWidthEqualTitle(boolean indicatorWidthEqualTitle) {
		this.mIndicatorWidthEqualTitle = indicatorWidthEqualTitle;
		invalidate();
	}

	public void setUnderlineColor(int underlineColor) {
		this.mUnderlineColor = underlineColor;
		invalidate();
	}

	public void setUnderlineHeight(float underlineHeight) {
		this.mUnderlineHeight = dp2px(underlineHeight);
		invalidate();
	}

	public void setUnderlineGravity(int underlineGravity) {
		this.mUnderlineGravity = underlineGravity;
		invalidate();
	}

	public void setDividerColor(int dividerColor) {
		this.mDividerColor = dividerColor;
		invalidate();
	}

	public void setDividerWidth(float dividerWidth) {
		this.mDividerWidth = dp2px(dividerWidth);
		invalidate();
	}

	public void setDividerPadding(float dividerPadding) {
		this.mDividerPadding = dp2px(dividerPadding);
		invalidate();
	}

	public void setTextsize(float textsize) {
		this.mTextsize = sp2px(textsize);
		updateTabStyles();
	}

	public void setTextSelectColor(int textSelectColor) {
		this.mTextSelectColor = textSelectColor;
		updateTabStyles();
	}

	public void setTextUnselectColor(int textUnselectColor) {
		this.mTextUnselectColor = textUnselectColor;
		updateTabStyles();
	}

	public void setTextBold(boolean textBold) {
		this.mTextBold = textBold;
		updateTabStyles();
	}

	public void setTextAllCaps(boolean textAllCaps) {
		this.mTextAllCaps = textAllCaps;
		updateTabStyles();
	}

	public int getTabCount() {
		return mTabCount;
	}

	public int getCurrentTab() {
		return mCurrentTab;
	}

	public int getIndicatorStyle() {
		return mIndicatorStyle;
	}

	public float getTabPadding() {
		return mTabPadding;
	}

	public boolean isTabSpaceEqual() {
		return mTabSpaceEqual;
	}

	public float getTabWidth() {
		return mTabWidth;
	}

	public int getIndicatorColor() {
		return mIndicatorColor;
	}

	public float getIndicatorHeight() {
		return mIndicatorHeight;
	}

	public float getIndicatorWidth() {
		return mIndicatorWidth;
	}

	public float getIndicatorCornerRadius() {
		return mIndicatorCornerRadius;
	}

	public float getIndicatorMarginLeft() {
		return mIndicatorMarginLeft;
	}

	public float getIndicatorMarginTop() {
		return mIndicatorMarginTop;
	}

	public float getIndicatorMarginRight() {
		return mIndicatorMarginRight;
	}

	public float getIndicatorMarginBottom() {
		return mIndicatorMarginBottom;
	}

	public int getUnderlineColor() {
		return mUnderlineColor;
	}

	public float getUnderlineHeight() {
		return mUnderlineHeight;
	}

	public int getDividerColor() {
		return mDividerColor;
	}

	public float getDividerWidth() {
		return mDividerWidth;
	}

	public float getDividerPadding() {
		return mDividerPadding;
	}

	public float getTextsize() {
		return mTextsize;
	}

	public int getTextSelectColor() {
		return mTextSelectColor;
	}

	public int getTextUnselectColor() {
		return mTextUnselectColor;
	}

	public boolean isTextBold() {
		return mTextBold;
	}

	public boolean isTextAllCaps() {
		return mTextAllCaps;
	}

	// setter and getter

	// show MsgTipView
	private Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
	private SparseArray<Boolean> mInitSetMap = new SparseArray<>();

	/**
	 * 显示未读消息
	 *
	 * @param position
	 *            显示tab位置
	 * @param num
	 *            num小于等于0显示红点,num大于0显示数字
	 */
	public void showMsg(int position, int num) {
		if (position >= mTabCount) {
			position = mTabCount - 1;
		}

		// View tabView = mTabsContainer.getChildAt(position);
		// RoundTextView tipView = (RoundTextView)
		// tabView.findViewById(R.id.rtv_msg_tip);
		// if (tipView != null) {
		// UnreadMsgUtils.show(tipView, num);
		//
		// if (mInitSetMap.get(position) != null && mInitSetMap.get(position)) {
		// return;
		// }
		//
		// setMsgMargin(position, 4, 2);
		// mInitSetMap.put(position, true);
		// }
	}

	/**
	 * 显示未读红点
	 *
	 * @param position
	 *            显示tab位置
	 */
	public void showDot(int position) {
		if (position >= mTabCount) {
			position = mTabCount - 1;
		}
		showMsg(position, 0);
	}

	/** 隐藏未读消息 */
	public void hideMsg(int position) {
		// if (position >= mTabCount) {
		// position = mTabCount - 1;
		// }
		//
		// View tabView = mTabsContainer.getChildAt(position);
		// RoundTextView tipView = (RoundTextView)
		// tabView.findViewById(R.id.rtv_msg_tip);
		// if (tipView != null) {
		// tipView.setVisibility(View.GONE);
		// }
	}

	/** 设置未读消息偏移,原点为文字的右上角.当控件高度固定,消息提示位置易控制,显示效果佳 */
	public void setMsgMargin(int position, float leftPadding,
							 float bottomPadding) {
		// if (position >= mTabCount) {
		// position = mTabCount - 1;
		// }
		// View tabView = mTabsContainer.getChildAt(position);
		// RoundTextView tipView = (RoundTextView)
		// tabView.findViewById(R.id.rtv_msg_tip);
		// if (tipView != null) {
		// TextView tv_tab_title = (TextView)
		// tabView.findViewById(R.id.tv_tab_title);
		// mTextPaint.setTextSize(mTextsize);
		// float textWidth =
		// mTextPaint.measureText(tv_tab_title.getText().toString());
		// float textHeight = mTextPaint.descent() - mTextPaint.ascent();
		// MarginLayoutParams lp = (MarginLayoutParams)
		// tipView.getLayoutParams();
		// lp.leftMargin = mTabWidth >= 0 ? (int) (mTabWidth / 2 + textWidth / 2
		// + dp2px(leftPadding)) : (int) (mTabPadding + textWidth +
		// dp2px(leftPadding));
		// lp.topMargin = mHeight > 0 ? (int) (mHeight - textHeight) / 2 -
		// dp2px(bottomPadding) : 0;
		// tipView.setLayoutParams(lp);
		// }
	}

	// /** 当前类只提供了少许设置未读消息属性的方法,可以通过该方法获取RoundTextView对象从而各种设置 */
	// public RoundTextView getMsgView(int position) {
	// if (position >= mTabCount) {
	// position = mTabCount - 1;
	// }
	// View tabView = mTabsContainer.getChildAt(position);
	// RoundTextView tipView = (RoundTextView)
	// tabView.findViewById(R.id.rtv_msg_tip);
	// return tipView;
	// }

	private OnTabSelectListener mListener;

	public void setOnTabSelectListener(OnTabSelectListener listener) {
		this.mListener = listener;
	}

	class InnerPagerAdapter extends FragmentPagerAdapter {
		private ArrayList<Fragment> fragments = new ArrayList<>();
		private String[] titles;

		public InnerPagerAdapter(FragmentManager fm,
								 ArrayList<Fragment> fragments, String[] titles) {
			super(fm);
			this.fragments = fragments;
			this.titles = titles;
		}

		@Override
		public int getCount() {
			return fragments.size();
		}

		@Override
		public CharSequence getPageTitle(int position) {
			return titles[position];
		}

		@Override
		public Fragment getItem(int position) {
			return fragments.get(position);
		}

		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			// 覆写destroyItem并且空实现,这样每个Fragment中的视图就不会被销毁
			// super.destroyItem(container, position, object);
		}

		@Override
		public int getItemPosition(Object object) {
			return PagerAdapter.POSITION_NONE;
		}
	}

	public interface CustomTabProvider {
		View getCustomTabView(ViewGroup parent, int position);

		void tabSelect(View tab);

		void tabUnselect(View tab);
	}

	@Override
	protected Parcelable onSaveInstanceState() {
		Bundle bundle = new Bundle();
		bundle.putParcelable("instanceState", super.onSaveInstanceState());
		bundle.putInt("mCurrentTab", mCurrentTab);
		return bundle;
	}

	@Override
	protected void onRestoreInstanceState(Parcelable state) {
		if (state instanceof Bundle) {
			Bundle bundle = (Bundle) state;
			mCurrentTab = bundle.getInt("mCurrentTab");
			state = bundle.getParcelable("instanceState");
			if (mCurrentTab != 0 && mTabsContainer.getChildCount() > 0) {
				updateTabSelection(mCurrentTab);
				scrollToCurrentTab();
			}
		}
		super.onRestoreInstanceState(state);
	}

	protected int dp2px(float dp) {
		final float scale = mContext.getResources().getDisplayMetrics().density;
		return (int) (dp * scale + 0.5f);
	}

	protected int sp2px(float sp) {
		final float scale = this.mContext.getResources().getDisplayMetrics().scaledDensity;
		return (int) (sp * scale + 0.5f);
	}
}
